import { ref } from 'vue'

export interface Product {
  id: number
  name: string
  price: number
  category: string
  cacheTime?: number
}

export function useIndexedDB() {
  const db = ref<IDBDatabase | null>(null)
  const dbName = 'ProductDatabase'
  const storeName = 'productStore'

  // 初始化数据库
  function initDatabase(): Promise<IDBDatabase> {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(dbName, 1)

      request.onupgradeneeded = (event) => {
        const database = event.target.result
        const objectStore = database.createObjectStore(storeName, {
          keyPath: 'id',
        })

        objectStore.createIndex('category', 'category', { unique: false })
        objectStore.createIndex('cacheTime', 'cacheTime', { unique: false })
      }

      request.onsuccess = (event) => {
        db.value = event.target.result
        resolve(db.value)
      }

      request.onerror = () => reject('数据库初始化失败')
    })
  }

  // 缓存商品数据
  function cacheProducts(newProducts: Product[]): Promise<void> {
    return new Promise(async (resolve, reject) => {
      if (!db.value) await initDatabase()

      const transaction = db.value!.transaction([storeName], 'readwrite')
      const store = transaction.objectStore(storeName)

      newProducts.forEach((product) => {
        store.put({
          ...product,
          cacheTime: Date.now(),
        })
      })

      transaction.oncomplete = () => resolve()
      transaction.onerror = () => reject('缓存失败')
    })
  }
  // 获取所有缓存数据
  async function getAllCachedProducts(): Promise<Product[]> {
    return new Promise(async (resolve, reject) => {
      try {
        if (!db.value) await initDatabase()
        const transaction = db.value!.transaction([storeName], 'readonly')
        const store = transaction.objectStore(storeName)
        const request = store.getAll()

        request.onsuccess = (event: Event) => {
          const result = (event.target as IDBRequest).result
          resolve(result || [])
        }

        request.onerror = () => reject('获取缓存失败')
      } catch (error) {
        reject(error)
      }
    })
  }
  // 分页获取商品
  function getProductsByPage(page: number, pageSize: number): Promise<Product[]> {
    return new Promise(async (resolve, reject) => {
      if (!db.value) await initDatabase()

      const transaction = db.value!.transaction([storeName], 'readonly')
      const store = transaction.objectStore(storeName)
      const request = store.openCursor()

      const products: Product[] = []
      let skipCount = (page - 1) * pageSize
      let loadedCount = 0

      request.onsuccess = (event) => {
        const cursor = event.target.result

        if (cursor) {
          if (skipCount > 0) {
            skipCount--
            cursor.continue()
            return
          }

          if (loadedCount < pageSize) {
            products.push(cursor.value)
            loadedCount++
            cursor.continue()
          } else {
            resolve(products)
          }
        } else {
          resolve(products)
        }
      }

      request.onerror = () => reject('加载失败')
    })
  }

  // 清理过期缓存
  function clearExpiredCache(maxAge = 24 * 60 * 60 * 1000): Promise<void> {
    return new Promise(async (resolve, reject) => {
      if (!db.value) await initDatabase()

      const transaction = db.value!.transaction([storeName], 'readwrite')
      const store = transaction.objectStore(storeName)
      const request = store.openCursor()

      request.onsuccess = (event) => {
        const cursor = event.target.result

        if (cursor) {
          const product = cursor.value
          if (Date.now() - product.cacheTime > maxAge) {
            cursor.delete()
          }
          cursor.continue()
        } else {
          resolve()
        }
      }

      request.onerror = () => reject('清理缓存失败')
    })
  }

  return {
    initDatabase,
    cacheProducts,
    getAllCachedProducts,
    getProductsByPage,
    clearExpiredCache,
  }
}
